package biz.inspeed.test.thread1;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class ProCon {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
//		Buffer buffer = new Buffer();
//		new Pro(buffer).start();
//		new Con1(buffer).start();
//		new Con1(buffer).start();
//		new Con1(buffer).start();
		Object lock = new Object();
		new Thread6281(lock).start();
		new Thread6281(lock).start();
	}

}

class Thread6281 extends Thread{
	Object lock;
	public Thread6281(Object lock){
		this.lock = lock;
	}
	@Override
	public void run() {
		synchronized (lock) {
			while(true){
				System.out.println(getName() + "\t" + "hello.");
				lock.notify();
				try {
					lock.wait();
					TimeUnit.SECONDS.sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
class Pro extends Thread{
	private Buffer buffer;
	public Pro(Buffer buffer){
		this.buffer = buffer;
	}
	@Override
	public void run() {
		while(true){
			String str =null;// String.valueOf(System.currentTimeMillis());
			str = String.valueOf((int)(Math.random()*1000));
			System.out.println("produce "+getId() +"\t"+ str);
			this.buffer.push(str);
			try {
				TimeUnit.SECONDS.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

class Con1 extends Thread{
	private Buffer buffer ;
	public Con1(Buffer buffer){
		this.buffer = buffer;
	}
	
	@Override
	public void run() {
		while(true){
			System.out.println("con " +getId() +"\t"+ this.buffer.pop());;
			try {
				TimeUnit.SECONDS.sleep(2);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
class Buffer{
	private List<String> data = new ArrayList<String>();
	
	public String pop(){
		synchronized (this) {
			if(this.data.isEmpty()){
				try {
					this.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			this.notifyAll();
			return this.data.remove(0);
		}
	}
	
	public void push(String str){
		synchronized (this) {
			if(this.data.size() >= 5){
				try {
					this.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			this.data.add(str);
			this.notifyAll();
		}
	}
}
